#pragma once
#include"InetAddr.hpp"


namespace kzz
{
    using _func_t=std::function<void (int sockfd,const std::string& word,InetAddr& _addr)     >;
    class UdpServer
    {
    public:
        UdpServer(uint16_t port,_func_t func)
            : _sockfd(-1), _port(port), _isrunning(false),_func(func)
        {
        }
        UdpServer(const kzz::UdpServer&)=default;
        UdpServer(kzz::UdpServer&&)=default;
        
        void Init()
        {
              _sockfd = socket(AF_INET, SOCK_DGRAM, 0);
            if (_sockfd < 0)
            {
                kzz::LOG(LogLevel::ERROR) << "server创建套接字失败";
                exit(1);
            }

            kzz::LOG(LogLevel::ERROR) << "server socket success,sockfd:" << _sockfd;
   
            kzz::InetAddr local(_port);
            //struct sockaddr_in local;

            int n = bind(_sockfd, local.Addr(), local.Len());

            if (n != 0)
            {
                kzz::LOG(LogLevel::ERROR) << "bind error";
                exit(1);
            }
            kzz::LOG(LogLevel::ERROR) << "bind success";
            
           
        }
       
        // 服务器接受数据，然后处理完发回去
        void Start()
        {
            _isrunning = true;
            while (_isrunning)
            {
                // 定义socke地址结构体,用来保存客户端的IP和端口号
               // kzz::InetAddr client_addr;
                
                char buffer[1024];
                 sockaddr_in client;
                socklen_t len=sizeof(client);
               
                ssize_t s=recvfrom(_sockfd,buffer,sizeof(buffer)-1,0,(sockaddr*)&client,&len);
                 kzz::InetAddr client_addr(client);
               if(s<0)
               {
                   kzz::LOG(LogLevel::DBUGER)<<"recvfrom fail";
                   exit(1);
               }
                if(s>0)
                {
                     std::string client_ip=client_addr.Ip();
                uint16_t client_port=client_addr.Port();
                    kzz::LOG(LogLevel::DBUGER)<<"服务器收取数据成功,客户端为"<<client_ip.c_str()<<' '<<client_port
                    <<"数据为: "<<buffer;

                ///对收到的数据处理，然后传回
                //buffer[0]='b';
                ///不理解为什么这么样不行
                //返回的是函数栈上的变量，函数销毁内存就没了
                //const std::string& result=_func(buffer,client_addr);
   
             //  std::string result=_func(buffer,client_addr);
                    _func(_sockfd,buffer,client_addr);
      
                //ssize_t n=sendto(_sockfd,result.c_str(),result.size(),0,client_addr.Addr(),client_addr.Len());

                 ///   if(n<0)
                 //   kzz::LOG(LogLevel::WORING)<<"server sendto fail !!!";

               }
               
            }
        }

    private:
        int _sockfd;
        uint16_t _port;
        _func_t _func;
        bool _isrunning;
    };
}